#include "EventManager.h"

namespace glow
{
	EventManager *EventManager::_inst = NULL;
	
	EventManager::EventManager()
	{
	}

	EventManager::~EventManager()
	{
	}

	void GLFWCALL eventKeyCallBack(int key, int action)
	{
		EventManager::getInstance()->eventKeyCB(key, action);
	}

	void EventManager::eventKeyCB(int key, int action)
	{
		_keyDown[key] = action;
	}

	void GLFWCALL eventMouseCallBack(int x, int y)
	{
		EventManager::getInstance()->eventMouseCB(x, y);
	}

	void EventManager::eventMouseCB(int x, int y)
	{
		_relX = _mouseX - _lastMouseX;
		_relY = _mouseY - _lastMouseY;
		_lastMouseX = _mouseX;
		_lastMouseY = _mouseY;
		_mouseX = x;
		_mouseY = y;
	}

	void GLFWCALL eventMouseButtonCallBack(int button, int action)
	{
		EventManager::getInstance()->eventMouseButtonCB(button, action);
	}

	void EventManager::eventMouseButtonCB(int button, int action)
	{
		_mouseButton[button] = action;
	}

	void EventManager::init(bool keyRepeat, bool stickyKeys, bool stickyMouseButtons)
	{
		for(int i=0; i<NBKEYS; i++)
			_keyDown[i] = _keyOnce[i] = GLFW_RELEASE;

		for(int i=0; i<NBMOUSEBUTTONS; i++)
			_mouseButton[i] = GLFW_RELEASE;

		glfwDisable(GLFW_AUTO_POLL_EVENTS);

		if(keyRepeat) glfwEnable(GLFW_KEY_REPEAT);
		if(stickyKeys) glfwEnable(GLFW_STICKY_KEYS);
		if(stickyMouseButtons) glfwEnable(GLFW_STICKY_MOUSE_BUTTONS);

		glfwSetKeyCallback(eventKeyCallBack);
		glfwSetMousePosCallback(eventMouseCallBack);
		glfwSetMouseButtonCallback(eventMouseButtonCallBack);
	}

	void EventManager::getEvent()
	{
		_relX = 0;
		_relY = 0;
		glfwPollEvents();
		_quit = !glfwGetWindowParam(GLFW_OPENED);
	}

	bool EventManager::isKeyDownOnce(int key)
	{
		if(!_keyOnce[key])
		{
			if(_keyDown[key])
			{
				_keyOnce[key] = true;
				return true;
			}
		}
		else if(!_keyDown[key])
			_keyOnce[key] = false;

		return false;
	}

	bool EventManager::isKeyDown(int key) const
	{
		return _keyDown[key];
	}

	bool EventManager::isMouseButtonUp(int button) const
	{
		return _mouseButton[button];
	}

	int EventManager::getMouseX() const
	{
		return _mouseX;
	}

	int EventManager::getMouseY() const
	{
		return _mouseY;
	}

	int EventManager::getRelMouseX() const
	{
		return _relX;
	}

	int EventManager::getRelMouseY() const
	{
		return _relY;
	}

	bool EventManager::EventManager::quit() const
	{
		return _quit;
	}
	
	EventManager *EventManager::getInstance()
	{
		if(!_inst)
			_inst = new EventManager();
		return _inst;
	}
	
	void EventManager::destroy()
	{
		if(_inst)
			delete _inst;
	}

}
